package xcmg.device.service.agent;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.agent.ServiceBorrowInDO;
import xcmg.device.dao.entity.agent.ServiceBorrowInDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseInboundDetailDO;
import xcmg.device.dao.mapper.agent.ServiceBorrowInDetailMapper;
import xcmg.device.dao.mapper.agent.ServiceBorrowInMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInboundDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseInboundMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.vo.agent.ServiceBorrowInDetailVO;
import xcmg.device.service.warehouse.WarehouseInboundService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * ServiceBorrowInDetail 后台接口实现类
 *
 * @author huhuawei
 */
@Service
public class ServiceBorrowInDetailService {
    private static final Logger logger = LoggerFactory.getLogger(ServiceBorrowInDetailService.class);
    @Autowired
    private ServiceBorrowInDetailMapper serviceBorrowInDetailMapper;
    @Autowired
    private FastGenClient fastGenClient;
    @Autowired
    private WarehouseInboundService warehouseInboundService;
    @Autowired
    private ServiceBorrowInMapper serviceBorrowInMapper;
    @Autowired
    private ServiceBorrowOutService serviceBorrowOutService;
    @Autowired
    private WarehouseInboundMapper warehouseInboundMapper;
    @Autowired
    private WarehouseInboundDetailMapper warehouseInboundDetailMapper;

    /**
     * 查询列表
     *
     * @param condition
     */
    public PageCommonVO<ServiceBorrowInDetailVO> list(SearchCommonVO<ServiceBorrowInDetailVO> condition) {
        if (null == condition.getFilters()) {
            condition.setFilters(new ServiceBorrowInDetailVO());
        }
        PageCommonVO<ServiceBorrowInDetailVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<ServiceBorrowInDetailDO> queryList = serviceBorrowInDetailMapper.queryList(condition.getFilters());
        List<ServiceBorrowInDetailVO> voList = new ArrayList<ServiceBorrowInDetailVO>();
        for (ServiceBorrowInDetailDO entity : queryList) {
            ServiceBorrowInDetailVO serviceBorrowInDetailVO = new ServiceBorrowInDetailVO();
            BeanUtils.copyProperties(entity, serviceBorrowInDetailVO);
            voList.add(serviceBorrowInDetailVO);
        }
        pageCommonVO.setPageInfo(new PageInfo(queryList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * 查询列表
     *
     * @param vo
     */
    public List<ServiceBorrowInDetailDO> queryList(ServiceBorrowInDetailVO vo) {
        return serviceBorrowInDetailMapper.queryList(vo);
    }


    /**
     * 查询单条记录
     *
     * @param id
     */
    public ServiceBorrowInDetailDO queryById(String id) {
        ServiceBorrowInDetailVO vo = new ServiceBorrowInDetailVO();
        vo.setId(id);
        List<ServiceBorrowInDetailDO> list = queryList(vo);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 保存数据
     *
     * @param serviceBorrowInDetailVO
     * @param userId
     * @param userName
     * @param orgId
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode save(ServiceBorrowInDetailVO serviceBorrowInDetailVO, String userId, String userName, String orgId) throws Exception {
        doSave(serviceBorrowInDetailVO, userId, userName, orgId);
        return ErrorCode.Success;
    }


    /**
     * 根据状态，等信息保存数据
     *
     * @param serviceBorrowInDetailVO
     * @param userId
     * @param userName
     * @param orgId
     */
    private ErrorCode doSave(ServiceBorrowInDetailVO serviceBorrowInDetailVO, String userId, String userName, String orgId) throws Exception {
        preSaveCheck(serviceBorrowInDetailVO);
        ServiceBorrowInDetailDO inDetailDO = new ServiceBorrowInDetailDO();
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }

        BigDecimal oldReturnQty = BigDecimal.ZERO;
        boolean isSuccess;
        if (StringUtils.isBlank(serviceBorrowInDetailVO.getId())) {
            BeanUtils.copyProperties(serviceBorrowInDetailVO, inDetailDO);
            inDetailDO.setId(textResult.getValue());
            // 0-未入库，1-部分入库，2-已入库，3-结单
            //新增的时候需要保存状态 默认出库数量为0
            inDetailDO.setStatus(0);
            inDetailDO.setThisReturnQty(new BigDecimal(0));
            isSuccess = this.merge(inDetailDO) > 0;
            logger.info("新增操作，serviceBorrowOutDetailDO:{}", inDetailDO);
        } else {
            ServiceBorrowInDetailDO serviceBorrowInDetailDO = serviceBorrowInDetailMapper.selectByPrimaryKey(serviceBorrowInDetailVO.getId());
            if (null != serviceBorrowInDetailDO) {
                oldReturnQty = serviceBorrowInDetailDO.getReturnQty();
            }

            inDetailDO.setId(serviceBorrowInDetailVO.getId());
            inDetailDO.setReturnQty(serviceBorrowInDetailVO.getReturnQty());
            inDetailDO.setStatus(serviceBorrowInDetailVO.getStatus());
            logger.info("编辑操作，serviceBorrowOutDetailDO:{}", inDetailDO);
            isSuccess = serviceBorrowInDetailMapper.updateByPrimaryKeySelective(inDetailDO) > 0;
            //更新出库基表的数量和状态
            ErrorCode errorCode = warehouseInboundService.updateDetailState(serviceBorrowInDetailVO.getBorrowInNo(),
                    serviceBorrowInDetailVO.getMaterialsNo(), inDetailDO.getReturnQty(), inDetailDO.getStatus(), orgId);
            if (errorCode.getCode() != 0) {
                throw new Exception("更新出库事物单详情记录失败");
            }

        }
        if (isSuccess) {
            //跟新转退回数量
            isSuccess = serviceBorrowOutService.updateRollBackQty(serviceBorrowInDetailVO.getBorrowOutDetailId(),
                    serviceBorrowInDetailVO.getReturnQty(), oldReturnQty);

        }

        if (!isSuccess) {
            return ErrorCode.Failure;
        }
        return ErrorCode.Success;
    }

    /**
     * 保存前信息校验
     */
    private void preSaveCheck(ServiceBorrowInDetailVO serviceBorrowInDetailVO) throws Exception {
        if (null == serviceBorrowInDetailVO) {
            throw new Exception(ErrorCode.IllegalArument.getDesc());
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public int merge(ServiceBorrowInDetailDO dto) {
        return serviceBorrowInDetailMapper.merge(dto);
    }

    /**
     * 批量删除
     *
     * @param ids
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode batchDelete(List<String> ids) throws Exception {
        if (CollectionUtils.isEmpty(ids)) {
            return ErrorCode.Failure;
        }
        for (String id : ids) {
            ServiceBorrowInDetailDO serviceBorrowInDetailDO = serviceBorrowInDetailMapper.selectByPrimaryKey(id);
            if (null != serviceBorrowInDetailDO && StringUtils.isNotBlank(serviceBorrowInDetailDO.getBorrowOutDetailId())) {
                boolean result = serviceBorrowOutService.updateRollBackQty(serviceBorrowInDetailDO.getBorrowOutDetailId(),
                        BigDecimal.ZERO, serviceBorrowInDetailDO.getReturnQty());
            }
            int i = serviceBorrowInDetailMapper.deleteByPrimaryKeySelective(id);
           /* if (i == 0) {
                throw new Exception(ErrorCode.Failure.getDesc());
            }*/
        }
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode deleteDetails(List<String> ids, String orgId) throws Exception {
        Map<String, ServiceBorrowInDO> serviceBorrowInDOTemp = new HashMap<>();
        for (String id : ids) {
            ServiceBorrowInDetailDO serviceBorrowInDetailDO = serviceBorrowInDetailMapper.selectByPrimaryKey(id);
            if (null == serviceBorrowInDetailDO || serviceBorrowInDetailDO.getStatus() != 0) {
                throw new Exception(ErrorCode.Failure.getDesc());
            }

            ServiceBorrowInDO borrowInDO = serviceBorrowInDOTemp.get("borrowInDO");
            if (borrowInDO == null) {
                ServiceBorrowInDO serviceBorrowInDO = serviceBorrowInMapper.selectByPrimaryKey(serviceBorrowInDetailDO.getBorrowInId());
                serviceBorrowInDOTemp.put("borrowInDO", serviceBorrowInDO);
            }

            //删除事物
            removeByBusinessOrders(orgId, serviceBorrowInDetailDO, serviceBorrowInDOTemp.get("borrowInDO"));
            // 回退转销售数量
            boolean result = serviceBorrowOutService.updateRollBackQty(serviceBorrowInDetailDO.getBorrowOutDetailId(),
                    BigDecimal.ZERO, serviceBorrowInDetailDO.getReturnQty());
            //删除详情表
            int delCount = serviceBorrowInDetailMapper.deleteByPrimaryKeySelective(id);
            if (delCount <= 0) {
                throw new Exception(ErrorCode.Failure.getDesc());
            }
        }
        return ErrorCode.Success;
    }

    private void removeByBusinessOrders(String orgId, ServiceBorrowInDetailDO serviceBorrowInDetailDO, ServiceBorrowInDO serviceBorrowInDO) throws Exception {
        String materialsNo = serviceBorrowInDetailDO.getMaterialsNo();
        String borrowInNo = serviceBorrowInDO.getBorrowInNo();
        WarehouseInboundDetailDO record = new WarehouseInboundDetailDO();
        record.setBusinessOrder(borrowInNo);
        record.setMaterialNo(materialsNo);
        record.setOrgId(orgId);
        int delCount = warehouseInboundDetailMapper.deleteByMaterial(record);
        if (delCount <= 0) {
            throw new Exception(ErrorCode.Failure.getDesc());
        }
    }

}
